/**
 * 
 */
package hawk.example.juni5.launcher;

import static org.junit.platform.engine.discovery.ClassNameFilter.includeClassNamePatterns;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectPackage;

import java.io.PrintWriter;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.platform.engine.FilterResult;
import org.junit.platform.engine.TestDescriptor;
import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.LauncherDiscoveryListener;
import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.junit.platform.launcher.LauncherSession;
import org.junit.platform.launcher.LauncherSessionListener;
import org.junit.platform.launcher.PostDiscoveryFilter;
import org.junit.platform.launcher.TestExecutionListener;
import org.junit.platform.launcher.TestPlan;
import org.junit.platform.launcher.core.LauncherConfig;
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
import org.junit.platform.launcher.core.LauncherFactory;
import org.junit.platform.launcher.listeners.SummaryGeneratingListener;
import org.junit.platform.launcher.listeners.TestExecutionSummary;
import org.junit.platform.reporting.legacy.xml.LegacyXmlReportGeneratingListener;

public class UsingTheLauncherDemo {

	@Test
	void discovery() {
		LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
				.selectors(
						selectPackage("hawk.example.juni5.launcher"),
						selectClass(MyTestClass.class))
				.filters(includeClassNamePatterns(".*Tests"))
				.build();
		;

		try (LauncherSession session = LauncherFactory.openSession()) {
			TestPlan testPlan = session.getLauncher().discover(request);
			// ... discover additional test plans or execute tests
		}
	}

	@Test
	@Tag("exclude")
	void execution() {
		LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
				.selectors(
						selectPackage("hawk.example.juni5.launcher"),
						selectClass(MyTestClass.class))
				.filters(includeClassNamePatterns(".*Tests"))
				.build();

		SummaryGeneratingListener listener = new SummaryGeneratingListener();

		try (LauncherSession session = LauncherFactory.openSession()) {
			Launcher launcher = session.getLauncher();
			// Register a listener of your choice
			launcher.registerTestExecutionListeners(listener);
			// Discover tests and build a test plan
			TestPlan testPlan = launcher.discover(request);
			// Execute test plan
			launcher.execute(testPlan);
			// Alternatively, execute the request directly
			launcher.execute(request);
		}

		TestExecutionSummary summary = listener.getSummary();
		// Do something with the summary...

	}

	@Test
	void launcherConfig() {
		Path reportsDir = Paths.get("target", "xml-reports");
		PrintWriter out = new PrintWriter(System.out);
		LauncherConfig launcherConfig = LauncherConfig.builder()
				.enableTestEngineAutoRegistration(false)
				.enableLauncherSessionListenerAutoRegistration(false)
				.enableLauncherDiscoveryListenerAutoRegistration(false)
				.enablePostDiscoveryFilterAutoRegistration(false)
				.enableTestExecutionListenerAutoRegistration(false)
				.addTestEngines(new CustomTestEngine())
				.addLauncherSessionListeners(new CustomLauncherSessionListener())
				.addLauncherDiscoveryListeners(new CustomLauncherDiscoveryListener())
				.addPostDiscoveryFilters(new CustomPostDiscoveryFilter())
				.addTestExecutionListeners(new LegacyXmlReportGeneratingListener(reportsDir, out))
				.addTestExecutionListeners(new CustomTestExecutionListener())
				.build();

		LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
				.selectors(selectPackage("hawk.example.juni5.launcher"))
				.build();

		try (LauncherSession session = LauncherFactory.openSession(launcherConfig)) {
			session.getLauncher().execute(request);
		}
	}

	class CustomTestExecutionListener implements TestExecutionListener {
	}

	class CustomLauncherSessionListener implements LauncherSessionListener {
	}

	class CustomLauncherDiscoveryListener implements LauncherDiscoveryListener {
	}

	class CustomPostDiscoveryFilter implements PostDiscoveryFilter {
		@Override
		public FilterResult apply(TestDescriptor object) {
			return FilterResult.included("includes everything");
		}
	}

}
